// ============================================================================
//
// Copyright (C) 2006-2007 Dengues
//
// Google Group: http://groups.google.com/group/dengues
// QQ Group: 24885404
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
// ============================================================================
package org.dengues.designer.core.sqldb;

import java.net.URL;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;

import org.dengues.commons.utils.DenguesTextUtil;
import org.dengues.core.ExceptionOperation;
import org.dengues.core.module.EClasspathVariables;
import org.dengues.designer.core.launch.DenguesProcessFactory;
import org.dengues.libraries.Activator;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.FileLocator;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Platform;
import org.eclipse.debug.core.ILaunch;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.osgi.util.ManifestElement;
import org.hsqldb.util.DatabaseManager;
import org.osgi.framework.Bundle;
import org.osgi.framework.Constants;

/**
 * Qiang.Zhang.Adolf@gmail.com class global comment. Detailled comment <br/>
 * 
 * $Id: Dengues.epf 1 2006-09-29 17:06:40Z qiang.zhang $ Utility class for starting HSQLDB tools
 */
public class SqldbUtil {

    /**
     * Qiang.Zhang.Adolf@gmail.com Comment method "getHsqldbJarPath".
     * 
     * @param variable
     * @return
     */
    public static String getHsqldbJarPath(final EClasspathVariables variable) {
        URL hsqldbJarURL = getHsqldbJarURL(variable);
        if (hsqldbJarURL != null) {
            return hsqldbJarURL.getPath();
        }
        return null;
    }

    // public static void createEmptyHsqlDatabase(String path) throws ClassNotFoundException, SQLException {
    // String url = "jdbc:hsqldb:" + path;
    // Class.forName("org.hsqldb.jdbcDriver");
    // Connection con = DriverManager.getConnection(url, "sa", "");
    // con.close();
    // }

    public static void runDatabaseManagerClient(IJavaProject proj) throws CoreException, ClassNotFoundException, SQLException {
        runDatabaseManager(proj, null);
    }

    public static void runDatabaseManagerStandalone(IJavaProject proj) throws CoreException, ClassNotFoundException, SQLException {
        String database = proj.getProject().getLocation() + SqldbServerTracker.HSQL_DATA_DIR;
        runDatabaseManager(proj, database);
    }

    public static boolean checkConnection() {
        boolean check = false;
        SqldbParams params = new SqldbParams();
        try {
            Class.forName(params.getDriver());
            String url = "jdbc:hsqldb:hsql://" + params.getHost() + ":" + params.getPort(); //$NON-NLS-1$ //$NON-NLS-2$
            Connection connection = DriverManager.getConnection(url, params.getUser(), params.getPassword());
            if (connection != null) {
                check = true;
                connection.close();
            }
        } catch (ClassNotFoundException ex) {
            ex.printStackTrace();
        } catch (SQLException ex) {
            // do nothing.
        } finally {
        }
        return check;
    }

    @SuppressWarnings("static-access")//$NON-NLS-1$
    private static void runDatabaseManager(IJavaProject proj, String database) throws CoreException, ClassNotFoundException,
            SQLException {
        SqldbParams params = new SqldbParams();
        String url = "jdbc:hsqldb:"; //$NON-NLS-1$
        if (database != null)
            url += database;
        else
            url += "hsql://127.0.0.1:" + params.getPort(); //$NON-NLS-1$
        Class.forName("org.hsqldb.jdbcDriver"); //$NON-NLS-1$
        Connection con = DriverManager.getConnection(url, params.getUser(), params.getPassword());
        if (con != null) {
            // needed to patch DatabaseManager so it could
            // be initialized and use the suplied connection
            DatabaseManager dm = new DatabaseManager();
            dm.main();
            dm.connect(con);
        }
    }

    public static ILaunch runScriptTool(IFile currentScript, String driver) throws CoreException {
        IJavaProject javaProj = JavaCore.create(currentScript.getProject());
        SqldbParams params = new SqldbParams();
        String fullPath = currentScript.getFullPath().removeFirstSegments(1).toPortableString();
        String args = "-driver " + driver + "-url jdbc:hsqldb:hsql: " + "-database //127.0.0.1:" //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
                + params.getPort() + " " + "-user " + params.getUser() + " " + "-script " + fullPath; //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
        if (params.getPassword().length() > 0)
            args += "-password " + params.getPassword() + " "; //$NON-NLS-1$ //$NON-NLS-2$
        return DenguesProcessFactory.launch(javaProj, fullPath + " (" + currentScript.getProject().getName() + ")", //$NON-NLS-1$ //$NON-NLS-2$
                "org.hsqldb.util.ScriptTool", args); //$NON-NLS-1$
    }

    public static String getStatusMessages(Exception e) {
        String msg = e.getMessage();
        if (e instanceof CoreException) {
            CoreException ce = (CoreException) e;
            IStatus status = ce.getStatus();
            IStatus[] children = status.getChildren();
            for (int i = 0; i < children.length; i++)
                msg += "\n" + children[i].getMessage(); //$NON-NLS-1$
            System.err.println(msg);
            ce.printStackTrace(System.err);
        }
        return msg;
    }

    /**
     * Qiang.Zhang.Adolf@gmail.com Comment method "runScriptTool".
     * 
     * @param scriptFile
     * @param driver
     * @param rootpath
     * @param database
     * @param schema
     * @param url
     * @param user
     * @param password
     * @return
     * @throws CoreException
     */
    public static ILaunch runScriptTool(IFile scriptFile, String driver, String rootpath, String database, String schema,
            String url, String user, String password) throws CoreException {
        IJavaProject javaProj = JavaCore.create(scriptFile.getProject());
        String fullPath = scriptFile.getFullPath().removeFirstSegments(1).toPortableString();
        String args = "-driver " + DenguesTextUtil.getNotNullString(driver) + " " //$NON-NLS-1$ //$NON-NLS-2$
                + "-url " + DenguesTextUtil.getNotNullString(url) + " " //$NON-NLS-1$ //$NON-NLS-2$
                + "-database " + DenguesTextUtil.getNotNullString(database) + " " //$NON-NLS-1$ //$NON-NLS-2$
                + "-user " + DenguesTextUtil.getNotNullString(user) + " " //$NON-NLS-1$ //$NON-NLS-2$
                + "-schema " + DenguesTextUtil.getNotNullString(schema) + " " //$NON-NLS-1$ //$NON-NLS-2$
                + "-rootpath " + DenguesTextUtil.getNotNullString(rootpath) + " " //$NON-NLS-1$ //$NON-NLS-2$
                + "-password " + DenguesTextUtil.getNotNullString(password) + " " //$NON-NLS-1$//$NON-NLS-2$
                + "-script " + DenguesTextUtil.getNotNullString(fullPath); //$NON-NLS-1$//$NON-NLS-2$
        return DenguesProcessFactory.launch(javaProj, fullPath + " (" + scriptFile.getProject().getName() + ")", //$NON-NLS-1$ //$NON-NLS-2$
                "dengues.system.ConnectivityUtils", args); //$NON-NLS-1$
    }

    /**
     * Qiang.Zhang.Adolf@gmail.com Comment method "getHsqldbJarURL".
     * 
     * @param variables
     * @return
     */
    public static URL getHsqldbJarURL(EClasspathVariables variable) {
        try {
            Bundle bundle = Platform.getBundle(Activator.PLUGIN_ID);
            String requires = (String) bundle.getHeaders().get(Constants.BUNDLE_CLASSPATH);
            ManifestElement[] elements = ManifestElement.parseHeader(Constants.BUNDLE_CLASSPATH, requires);
            URL hsqldbJar = null;
            // there's only one library on the hsqldb.core plug-in
            String value = elements[0].getValue();
            for (ManifestElement element : elements) {
                if (element.getValue().equals(variable.getJarname())) { //$NON-NLS-1$
                    value = element.getValue();
                    break;
                }
            }
            hsqldbJar = FileLocator.toFileURL(bundle.getEntry(value));
            return hsqldbJar;
            // }
        }
        // ignore URL-generated exceptions
        catch (Exception e) {
            ExceptionOperation.operate(e);
        }
        return null;
    }
}
